#pragma once

// To link against GlutApplication you need to add
// -lGL -lglut


namespace one_rag {
  namespace App {

    struct GlutAppDelegate {
      virtual void OnIdle(){}
      virtual void OnTimer(int timerId){}
    };

    enum eGlutAppCallbacks
    {
      GlutAppCallbackAll  = 0,
      GlutAppCallbackIdle = 1
    };

    namespace impl {

      struct GlutWindow;

      struct GlutApp : ApplicationBase {
      public:// Glut specific interface
        GlutApp();
        ~GlutApp();
        static void Init(int* argc, char** argv);
        static void MainLoop();

        static void InitDisplayMode(int mode);
        static void InitWindowPosition(int w, int h);
        static void InitWindowSize(int cx, int cy);

               void SetDelegate(GlutAppDelegate* appDelegate,unsigned int glutAppCallbackFlags=GlutAppCallbackAll);
        static void SetTimer(int msec,int timerId);

      private:
        static void timerFunc(int timerId);
        static void idleFunc();
      private:
        static GlutApp* _self;
        GlutAppDelegate* _appDelegate;

      public: // Standard Application API.
        GlutApp(int* argc, char** argv){
          _appDelegate=0; _self=this;
          Init(argc,argv);
        }
        void Run(){
          MainLoop();
        }

        public: // Standard exposed types
        typedef GlutWindow GLWindow;
        typedef GlutWindow Window;
      };

    }

    typedef impl::GlutApp GlutApplication;
  }
}
